package com.tao.content.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.tao.base.dictionary.CourseAuditStatus;
import com.tao.base.exception.LearnHubException;
import com.tao.base.model.PageResult;
import com.tao.content.domain.dto.AddCourseDto;
import com.tao.content.domain.dto.SelectCourseDto;
import com.tao.content.domain.dto.UpdateCourseDto;
import com.tao.content.domain.pojo.*;
import com.tao.content.domain.vo.CourseBaseInfoVo;
import com.tao.content.domain.vo.CourseVo;
import com.tao.content.mapper.CourseBaseMapper;
import com.tao.content.service.ICourseBaseService;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.List;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author taohongrun
 * @since 2024-11-01
 */
@Service
@Slf4j
@Validated
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements ICourseBaseService {

    @Override
    public PageResult<CourseVo> coursePage(SelectCourseDto selectCourseDto) {
        log.info("查询条件为:{}", selectCourseDto);
        Page<CourseBase> selectCourseDtoPage = selectCourseDto.toPage();
        Page<CourseBase> courseBasePage = lambdaQuery()
                .like(selectCourseDto.getCourseName() != null, CourseBase::getName, selectCourseDto.getCourseName())
                .eq(selectCourseDto.getAuditStatus() != null, CourseBase::getAuditStatus, selectCourseDto.getAuditStatus())
                .eq(selectCourseDto.getStatus() != null, CourseBase::getStatus, selectCourseDto.getStatus())
                .page(selectCourseDtoPage);
        log.info("初始查询结果为:{},数据当前页数为:{},数据总数为:{},每页大小为:{}", courseBasePage.getRecords(), courseBasePage.getPages(), courseBasePage.getTotal(), courseBasePage.getSize());
        List<CourseVo> courseVoList = courseBasePage.getRecords().stream()
                .map(m -> {
                    CourseVo courseVo = new CourseVo();
                    BeanUtils.copyProperties(m, courseVo);
                    return courseVo;
                })
                .toList();
        log.info("返回的数据为:{}", courseVoList);
        return PageResult.of(courseBasePage, courseVoList);
    }

    @Override
    @Transactional
    public CourseBaseInfoVo addCourse(@Valid AddCourseDto addCourseDto, Long companyId) {
        //创建要添加的对象，并为其赋基本值
        CourseBase courseBase = new CourseBase();
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(addCourseDto, courseMarket);
        BeanUtils.copyProperties(addCourseDto, courseBase);

        //为coursebase赋值其他值
        //设置审核状态
        courseBase.setAuditStatus("202002");
        //设置发布状态
        courseBase.setStatus("203001");
        courseBase.setCompanyId(companyId);
        this.save(courseBase);
        log.info("成功添加课程基本数据:{}", courseBase);

        //为courseMarket赋其他值
        courseMarket.setId(courseBase.getId());//与courseBase表为1对1关系，主键要一样
        //异常处理
        if (courseMarket.getCharge().equals("201001"))
            if (courseMarket.getPrice() == null || courseMarket.getPrice() <= 0) {
                throw new LearnHubException("课程为收费价格不能为空且必须大于0");
            }

        //防止出现id对不上号的情况，利用saveorupdate
        Db.saveOrUpdate(courseMarket);
        log.info("成功添加课程营销数据:{}", courseMarket);

        //封装VO进行返回，因为以后的vo可能与现在的vo一样，因此建议封装vo的过程定义为函数，可以复用
        //基本数据已经保存，传id即可获取全部信息
        return toCourseBaseInfoVo(courseBase.getId());

    }

    private CourseBaseInfoVo toCourseBaseInfoVo(Long courseId) {
        CourseBaseInfoVo courseBaseInfoVo = new CourseBaseInfoVo();
        CourseBase courseBase = getById(courseId);
        CourseMarket courseMarket = Db.getById(courseId, CourseMarket.class);
        BeanUtils.copyProperties(courseBase, courseBaseInfoVo);
        BeanUtils.copyProperties(courseMarket, courseBaseInfoVo);
        CourseCategory courseStCategory = Db.getById(courseBase.getSt(), CourseCategory.class);
        courseBaseInfoVo.setStName(courseStCategory.getName());
        CourseCategory courseMtCategory = Db.getById(courseBase.getMt(), CourseCategory.class);
        courseBaseInfoVo.setMtName(courseMtCategory.getName());
        log.info("转换后的addCourseBaseInfoVo为：{}", courseBaseInfoVo);
        return courseBaseInfoVo;
    }

    @Override
    public CourseBaseInfoVo getCourse(Long id) {
        return toCourseBaseInfoVo(id);
    }

    @Override
    @Transactional
    public CourseBaseInfoVo updateCourse(UpdateCourseDto updateCourseDto, Long companyId) {
        //具体业务合法性校验，只能修改本机构id
        // TODO: 2024/11/5 查询companyId对应的name，判断是否为同一机构

        //封装数据
        CourseBase courseBase = new CourseBase();
        CourseMarket courseMarket = new CourseMarket();
        BeanUtils.copyProperties(updateCourseDto, courseBase);
        BeanUtils.copyProperties(updateCourseDto, courseMarket);

        courseBase.setCompanyId(companyId);
        // TODO: 2024/11/5 设置机构名称

        updateById(courseBase);
        log.info("成功修改课程基本信息为:{}", courseBase);
        Db.updateById(courseMarket);
        log.info("成功修改课程营销信息为:{}", courseMarket);

        return toCourseBaseInfoVo(updateCourseDto.getId());
    }

    @Override
    public void removeCourse(Long id) {
        //课程的审核状态为未提交时方可删除
        //需要删除课程计划，课程教师，课程计划媒资，课程营销，课程基本信息
        String auditStatus = getById(id).getAuditStatus();
        log.info(auditStatus);
        log.info(CourseAuditStatus.NOT_COMMIT);
        if (!auditStatus.equals(CourseAuditStatus.NOT_COMMIT)) LearnHubException.throwMyException("课程已经提交，无法删除");
        Db.lambdaUpdate(Teachplan.class)
                .eq(Teachplan::getCourseId, id)
                .remove();
        log.info("成功删除课程计划");
        Db.lambdaUpdate(TeachplanMedia.class)
                .eq(TeachplanMedia::getCourseId, id)
                .remove();
        log.info("成功删除课程计划媒资");
        Db.lambdaUpdate(CourseTeacher.class)
                .eq(CourseTeacher::getCourseId, id)
                .remove();
        log.info("成功删除课程教师");
        Db.removeById(id,CourseMarket.class);
        log.info("成功删除课程营销");
        removeById(id);
        log.info("成功删除课程基本信息");
    }
}
